import { NextRequest, NextResponse } from 'next/server'
import { GloableResponseItem, ResponseEnum } from '@/utils/request/res'
import { Auth, DbScheme, type ExtendedNextApiRequest, generateToken, hashPassword, LogOperation, ResponseHandler, verifyPassword, verifyToken } from '@/utils/decorator'
import prisma from '@/utils/db/PrismaService'
import { BaseController } from '@/utils/request/BaseController'
import { getCurrentTimeInShanghai } from '@/utils'
import { createNoticeSchema, updateNoticeSchema } from '@/dbSchema/systemSchema'
import { GET as HttpGet, POST as HttpPost, PUT as HttpPut, DELETE as HttpDelete } from '@/utils/decorator'
import { createAllMethodHandlers } from '@/utils/request/routeRegistry'
import { Prisma } from '@prisma/client'
import { eventEmitter } from '@/utils/sse/EventEmitter'
import { PrismaClient } from '@prisma/client'
import os from 'os'

class SystemHomeController extends BaseController {

    /**
     * 获取系统统计概览数据
     */
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getSystemStats(request: ExtendedNextApiRequest) {
        try {
            // 获取当前时间信息
            const now = new Date();
            const todayStart = new Date(now.getFullYear(), now.getMonth(), now.getDate());
            const todayEnd = new Date(todayStart);
            todayEnd.setDate(todayEnd.getDate() + 1);

            // 并行查询各种统计数据
            const [
                userStats,
                deptStats,
                dictStats,
                logStats,
                timerStats,
                settingStats,
                noticeStats
            ] = await Promise.all([
                // 用户统计
                prisma.$queryRaw<any[]>(Prisma.sql`
                    SELECT 
                        COUNT(*) as total_count,
                        COUNT(CASE WHEN status = '0' THEN 1 END) as active_count,
                        COUNT(CASE WHEN status = '1' THEN 1 END) as inactive_count
                    FROM sys_user WHERE del_flag = 1
                `),

                // 部门统计
                prisma.$queryRaw<any[]>(Prisma.sql`
                    SELECT 
                        COUNT(*) as total_count,
                        COUNT(CASE WHEN level = 1 THEN 1 END) as city_count,
                        COUNT(CASE WHEN level = 2 THEN 1 END) as county_count,
                        COUNT(CASE WHEN level = 3 THEN 1 END) as street_count,
                        COUNT(CASE WHEN level = 4 THEN 1 END) as institution_count
                    FROM sys_dept WHERE del_flag = 1
                `),

                // 字典统计
                prisma.$queryRaw<any[]>(Prisma.sql`
                    SELECT 
                        COUNT(*) as total_count,
                        COUNT(DISTINCT dict_type) as type_count
                    FROM sys_dict WHERE del_flag = 1
                `),

                // 今日日志统计
                prisma.$queryRaw<any[]>(Prisma.sql`
                    SELECT 
                        COUNT(*) as today_count,
                        COUNT(CASE WHEN status = 0 THEN 1 END) as success_count,
                        COUNT(CASE WHEN status = 1 THEN 1 END) as error_count,
                        AVG(cost_time) as avg_cost_time
                    FROM sys_log 
                    WHERE operation_time >= ${todayStart} AND operation_time < ${todayEnd}
                `),

                // 定时任务统计
                prisma.$queryRaw<any[]>(Prisma.sql`
                    SELECT 
                        COUNT(*) as total_count,
                        COUNT(CASE WHEN status = 1 THEN 1 END) as active_count,
                        COUNT(CASE WHEN status = 0 THEN 1 END) as inactive_count
                    FROM sys_timer_task WHERE del_flag = 1
                `),

                // 系统配置统计
                prisma.$queryRaw<any[]>(Prisma.sql`
                    SELECT 
                        COUNT(*) as total_count,
                        COUNT(DISTINCT config_type) as type_count,
                        COUNT(CASE WHEN is_encrypted = 1 THEN 1 END) as encrypted_count
                    FROM sys_setting WHERE del_flag = 1
                `),

                // 通知统计
                prisma.$queryRaw<any[]>(Prisma.sql`
                    SELECT 
                        COUNT(*) as total_count,
                        COUNT(CASE WHEN status = 1 THEN 1 END) as sent_count,
                        COUNT(CASE WHEN status = 0 THEN 1 END) as draft_count
                    FROM sys_notice WHERE del_flag = 1
                `),
            ]);

            // 格式化统计数据
            const systemStats = {
                // 用户统计
                users: {
                    total: Number(userStats[0]?.total_count || 0),
                    active: Number(userStats[0]?.active_count || 0),
                    inactive: Number(userStats[0]?.inactive_count || 0)
                },

                // 部门统计
                departments: {
                    total: Number(deptStats[0]?.total_count || 0),
                    city: Number(deptStats[0]?.city_count || 0),
                    county: Number(deptStats[0]?.county_count || 0),
                    street: Number(deptStats[0]?.street_count || 0),
                    institution: Number(deptStats[0]?.institution_count || 0)
                },

                // 字典统计
                dictionaries: {
                    total: Number(dictStats[0]?.total_count || 0),
                    types: Number(dictStats[0]?.type_count || 0)
                },

                // 今日日志统计
                todayLogs: {
                    total: Number(logStats[0]?.today_count || 0),
                    success: Number(logStats[0]?.success_count || 0),
                    error: Number(logStats[0]?.error_count || 0),
                    avgCostTime: Number(logStats[0]?.avg_cost_time || 0)
                },

                // 定时任务统计
                timerTasks: {
                    total: Number(timerStats[0]?.total_count || 0),
                    active: Number(timerStats[0]?.active_count || 0),
                    inactive: Number(timerStats[0]?.inactive_count || 0)
                },

                // 系统配置统计
                settings: {
                    total: Number(settingStats[0]?.total_count || 0),
                    types: Number(settingStats[0]?.type_count || 0),
                    encrypted: Number(settingStats[0]?.encrypted_count || 0)
                },

                // 通知统计
                notices: {
                    total: Number(noticeStats[0]?.total_count || 0),
                    sent: Number(noticeStats[0]?.sent_count || 0),
                    draft: Number(noticeStats[0]?.draft_count || 0)
                }
            };

            return GloableResponseItem(ResponseEnum.success, "", systemStats);
        } catch (error) {
            return GloableResponseItem(ResponseEnum.error, "获取系统统计失败", null);
        }
    }

    /**
     * 获取系统健康状态
     */
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getSystemHealth(request: ExtendedNextApiRequest) {
        try {
            const memoryUsage = process.memoryUsage();

            // 获取系统总内存
            const totalSystemMemory = os.totalmem();
            const freeSystemMemory = os.freemem();
            const usedSystemMemory = totalSystemMemory - freeSystemMemory;

            const healthData = {
                database: {
                    status: 'healthy',
                    connectionCount: 0,
                    responseTime: 0,
                    type: 'PostgreSQL',
                    version: 'Unknown',
                    size: '0 MB',
                    sizeBytes: 0,
                    tableCount: 0,
                    connections: {
                        total: 0,
                        active: 0,
                        idle: 0
                    }
                },
                server: {
                    uptime: process.uptime(),
                    memory: {
                        // Node.js 内存信息
                        rss: memoryUsage.rss,           // 常驻内存大小
                        heapTotal: memoryUsage.heapTotal, // 堆内存总大小
                        heapUsed: memoryUsage.heapUsed,   // 已使用堆内存
                        external: memoryUsage.external,   // 外部内存使用
                        arrayBuffers: memoryUsage.arrayBuffers, // ArrayBuffer 内存

                        // 系统内存信息
                        systemTotal: totalSystemMemory,    // 系统总内存
                        systemFree: freeSystemMemory,      // 系统空闲内存
                        systemUsed: usedSystemMemory,      // 系统已用内存

                        // 内存使用率计算 - 使用系统内存
                        used: usedSystemMemory,            // 显示系统已用内存
                        total: totalSystemMemory,          // 显示系统总内存
                        usagePercent: Math.round((usedSystemMemory / totalSystemMemory) * 100),

                        // Node.js 进程内存使用率
                        processUsagePercent: Math.round((memoryUsage.rss / totalSystemMemory) * 100),
                        heapUsagePercent: Math.round((memoryUsage.heapUsed / memoryUsage.heapTotal) * 100)
                    },
                    nodeVersion: process.version,
                    // 添加系统平台信息
                    platform: process.platform,
                    arch: process.arch,
                    pid: process.pid,

                    // 添加CPU信息
                    cpuInfo: {
                        model: os.cpus()[0]?.model || 'Unknown',
                        cores: os.cpus().length,
                        loadAverage: os.loadavg()
                    }
                },
                application: {
                    status: 'running',
                    version: '1.0.0',
                    environment: process.env.NODE_ENV || 'development'
                }
            };

            // 测试数据库连接
            const start = Date.now();
            try {
                // 基础连接测试
                await prisma.$queryRaw(Prisma.sql`SELECT 1`);
                healthData.database.responseTime = Date.now() - start;
                healthData.database.status = 'healthy';

                // 获取数据库详细信息
                const [dbVersion, dbSize, tableCount, connectionStats] = await Promise.all([
                    // 获取数据库版本
                    prisma.$queryRaw<any[]>(Prisma.sql`SELECT version()`),

                    // 获取数据库大小（PostgreSQL）
                    prisma.$queryRaw<any[]>(Prisma.sql`
                        SELECT pg_size_pretty(pg_database_size(current_database())) as size,
                               pg_database_size(current_database()) as size_bytes
                    `),

                    // 获取表数量
                    prisma.$queryRaw<any[]>(Prisma.sql`
                        SELECT COUNT(*) as table_count 
                        FROM information_schema.tables 
                        WHERE table_schema = 'public' AND table_type = 'BASE TABLE'
                    `),

                    // 获取连接统计
                    prisma.$queryRaw<any[]>(Prisma.sql`
                        SELECT 
                            COUNT(*) as total_connections,
                            COUNT(CASE WHEN state = 'active' THEN 1 END) as active_connections,
                            COUNT(CASE WHEN state = 'idle' THEN 1 END) as idle_connections
                        FROM pg_stat_activity 
                        WHERE datname = current_database()
                    `)
                ]);

                // 更新数据库详细信息
                healthData.database.version = dbVersion[0]?.version?.split(' ')[1] || 'Unknown';
                healthData.database.size = dbSize[0]?.size || '0 MB';
                healthData.database.sizeBytes = Number(dbSize[0]?.size_bytes || 0);
                healthData.database.tableCount = Number(tableCount[0]?.table_count || 0);
                healthData.database.connections.total = Number(connectionStats[0]?.total_connections || 0);
                healthData.database.connections.active = Number(connectionStats[0]?.active_connections || 0);
                healthData.database.connections.idle = Number(connectionStats[0]?.idle_connections || 0);

            } catch (error) {
                healthData.database.status = 'unhealthy';
                healthData.database.responseTime = Date.now() - start;
                // 保持默认值即可，已在初始化时设置
            }

            return GloableResponseItem(ResponseEnum.success, "", healthData);
        } catch (error) {
            return GloableResponseItem(ResponseEnum.error, "获取系统健康状态失败", null);
        }
    }

    /**
     * 获取实时监控数据
     */
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getRealTimeMonitor(request: ExtendedNextApiRequest) {
        try {
            const now = new Date();
            const pastHour = new Date(now.getTime() - 60 * 60 * 1000);
            const past24Hours = new Date(now.getTime() - 24 * 60 * 60 * 1000);

            // 获取最近1小时的系统活动
            const [
                recentLogs,
                recentErrors,
                taskExecutions,
                activeUsers
            ] = await Promise.all([
                // 最近1小时日志统计
                prisma.$queryRaw<any[]>(Prisma.sql`
                    SELECT 
                        DATE_TRUNC('minute', operation_time) as time_bucket,
                        COUNT(*) as count,
                        COUNT(CASE WHEN status = 1 THEN 1 END) as error_count
                    FROM sys_log 
                    WHERE operation_time >= ${pastHour}
                    GROUP BY time_bucket
                    ORDER BY time_bucket DESC
                    LIMIT 60
                `),

                // 最近错误日志
                prisma.$queryRaw<any[]>(Prisma.sql`
                    SELECT 
                        module, operation_name, user_name, error_msg, operation_time
                    FROM sys_log 
                    WHERE status = 1 AND operation_time >= ${past24Hours}
                    ORDER BY operation_time DESC
                    LIMIT 10
                `),

                // 最近任务执行
                prisma.$queryRaw<any[]>(Prisma.sql`
                    SELECT 
                        t.task_name, l.execute_time, l.status, l.cost_time, l.error_msg
                    FROM sys_timer_log l
                    JOIN sys_timer_task t ON l.task_id = t.id
                    WHERE l.execute_time >= '${past24Hours.toISOString()}'
                    ORDER BY l.execute_time DESC
                    LIMIT 20
                `),

                // 活跃用户统计（基于最近24小时的日志）
                prisma.$queryRaw<any[]>(Prisma.sql`
                    SELECT 
                        user_name, COUNT(*) as operation_count,
                        MAX(operation_time) as last_operation
                    FROM sys_log 
                    WHERE operation_time >= ${past24Hours} AND user_name IS NOT NULL
                    GROUP BY user_name
                    ORDER BY operation_count DESC
                    LIMIT 10
                `)
            ]);

            const monitorData = {
                activityChart: recentLogs.map(item => ({
                    time: item.time_bucket,
                    operations: Number(item.count),
                    errors: Number(item.error_count)
                })),
                recentErrors: recentErrors.map(item => ({
                    ...item,
                    operation_time: item.operation_time
                })),
                taskExecutions: taskExecutions.map(item => ({
                    ...item,
                    cost_time: Number(item.cost_time)
                })),
                activeUsers: activeUsers.map(item => ({
                    ...item,
                    operation_count: Number(item.operation_count)
                }))
            };

            return GloableResponseItem(ResponseEnum.success, "", monitorData);
        } catch (error) {
            console.error('获取实时监控数据失败:', error);
            return GloableResponseItem(ResponseEnum.error, "获取实时监控数据失败", null);
        }
    }

    /**
     * 获取系统性能趋势数据
     */
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getPerformanceTrends(request: ExtendedNextApiRequest) {
        try {
            const params = request.customBody;
            const days = parseInt(params.days || '7'); // 默认7天
            const startDate = new Date();
            startDate.setDate(startDate.getDate() - days);

            // 获取每日统计数据
            const dailyStats = await prisma.$queryRaw<any[]>(Prisma.sql`
                SELECT 
                    DATE(operation_time) as date,
                    COUNT(*) as total_operations,
                    COUNT(CASE WHEN status = 1 THEN 1 END) as error_operations,
                    AVG(cost_time) as avg_response_time,
                    COUNT(DISTINCT user_name) as active_users
                FROM sys_log 
                WHERE operation_time >= ${startDate}
                GROUP BY DATE(operation_time)
                ORDER BY date ASC
            `);

            // 获取模块使用统计
            const moduleStats = await prisma.$queryRaw<any[]>(Prisma.sql`
                SELECT 
                    module,
                    COUNT(*) as operation_count,
                    COUNT(CASE WHEN status = 1 THEN 1 END) as error_count
                FROM sys_log 
                WHERE operation_time >= ${startDate}
                GROUP BY module
                ORDER BY operation_count DESC
                LIMIT 10
            `);

            const trendsData = {
                dailyStats: dailyStats.map(item => ({
                    date: item.date,
                    totalOperations: Number(item.total_operations),
                    errorOperations: Number(item.error_operations),
                    avgResponseTime: Number(item.avg_response_time || 0),
                    activeUsers: Number(item.active_users)
                })),
                moduleStats: moduleStats.map(item => ({
                    module: item.module,
                    operationCount: Number(item.operation_count),
                    errorCount: Number(item.error_count),
                    errorRate: Number(item.error_count) / Number(item.operation_count) * 100
                }))
            };

            return GloableResponseItem(ResponseEnum.success, "", trendsData);
        } catch (error) {
            console.error('获取性能趋势数据失败:', error);
            return GloableResponseItem(ResponseEnum.error, "获取性能趋势数据失败", null);
        }
    }

    /**
     * 获取系统并发监控数据
     */
    @Auth()
    @ResponseHandler()
    @HttpGet()
    static async getConcurrencyMonitor(request: ExtendedNextApiRequest) {
        try {
            const now = new Date();
            const oneMinuteAgo = new Date(now.getTime() - 60 * 1000);
            const fiveMinutesAgo = new Date(now.getTime() - 5 * 60 * 1000);

            // 获取最近1分钟和5分钟的请求统计
            const [
                currentMinuteStats,
                last5MinutesStats
            ] = await Promise.all([
                // 最近1分钟的请求统计
                prisma.$queryRaw<any[]>(Prisma.sql`
                    SELECT 
                        COUNT(*) as total_requests,
                        COUNT(CASE WHEN status = 0 THEN 1 END) as success_requests,
                        COUNT(CASE WHEN status = 1 THEN 1 END) as error_requests,
                        AVG(cost_time) as avg_response_time
                    FROM sys_log 
                    WHERE operation_time >= ${oneMinuteAgo}
                `),

                // 最近5分钟每分钟的统计（用于计算峰值）
                prisma.$queryRaw<any[]>(Prisma.sql`
                    SELECT 
                        DATE_TRUNC('minute', operation_time) as minute,
                        COUNT(*) as request_count,
                        COUNT(CASE WHEN status = 1 THEN 1 END) as error_count
                    FROM sys_log 
                    WHERE operation_time >= ${fiveMinutesAgo}
                    GROUP BY DATE_TRUNC('minute', operation_time)
                    ORDER BY minute DESC
                    LIMIT 5
                `)
            ]);

            // 计算当前并发数（最近1分钟的请求数）
            const currentConcurrency = Number(currentMinuteStats[0]?.total_requests || 0);

            // 计算最高并发数（最近5分钟内的最大值）
            const maxConcurrency = last5MinutesStats.length > 0 ?
                Math.max(...last5MinutesStats.map(item => Number(item.request_count || 0))) : 0;

            const concurrencyData = {
                // 当前并发指标
                current: {
                    concurrency: currentConcurrency,
                    successRate: currentMinuteStats[0] && Number(currentMinuteStats[0].total_requests) > 0 ?
                        Math.round((Number(currentMinuteStats[0].success_requests) / Number(currentMinuteStats[0].total_requests)) * 100) : 100,
                    avgResponseTime: Math.round(Number(currentMinuteStats[0]?.avg_response_time || 0)),
                    status: currentConcurrency > 50 ? 'high' : currentConcurrency > 20 ? 'medium' : 'low'
                },

                // 峰值数据
                peak: {
                    maxConcurrency: maxConcurrency,
                    peakTime: last5MinutesStats.length > 0 ?
                        last5MinutesStats.reduce((max, item) =>
                            Number(item.request_count) > Number(max.request_count) ? item : max
                        ).minute : null
                },

                // 趋势数据（最近5分钟）
                trends: last5MinutesStats.map(item => ({
                    time: item.minute,
                    requests: Number(item.request_count),
                    errors: Number(item.error_count)
                })),

                // 系统负载级别
                loadLevel: {
                    level: maxConcurrency > 100 ? 'high' : maxConcurrency > 50 ? 'medium' : 'low',
                    description: maxConcurrency > 100 ? '高负载' : maxConcurrency > 50 ? '中等负载' : '低负载'
                }
            };

            return GloableResponseItem(ResponseEnum.success, "", concurrencyData);
        } catch (error) {
            console.error('获取并发监控数据失败:', error);
            return GloableResponseItem(ResponseEnum.error, "获取并发监控数据失败", null);
        }
    }
}

// 使用自动路由处理器创建所有HTTP方法处理函数
const handlers = createAllMethodHandlers(SystemHomeController)

export const { GET, POST, PUT, DELETE } = handlers 